package byron.client;

import java.util.Collection;
import java.util.List;


import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.googlecode.gchart.client.GChart;
import com.googlecode.gchart.client.GChart.Curve;
import com.googlecode.gchart.client.GChart.Curve.Point;

/**
 * Class representing a single chart, with associated components for changing various attributes.
 *
 */
public class ChartPanel extends VerticalPanel{
	private GChart chart;
	private ListBox xBox, yBox;
	private SuggestBox suggBox;
	private MultiWordSuggestOracle oracle;
	
	public ChartPanel(GChart chart, List<String> attributes, List<String> suggestions) {
		super();
		this.chart = chart;
		
		HorizontalPanel hp = new HorizontalPanel();
		
		xBox = new ListBox();
		yBox = new ListBox();
		if (attributes != null) {
			for (String attribute : attributes) {
				xBox.addItem(attribute);
				yBox.addItem(attribute);
			}
		}
		
		hp.add(xBox);
		hp.add(yBox);

		oracle = new MultiWordSuggestOracle();
		suggBox = new SuggestBox(oracle);

		if (suggestions != null) {
			suggBox.showSuggestionList();
			setSuggestions(suggestions);
		}
		
		hp.add(suggBox);
		
		add(chart);
		add(hp);
		
		chart.update();
	}
	
	/**
	 *  @see ByronClient.setAttributes
	 */
	public void setAttributes(List<String> attributes) {
		xBox.clear();
		yBox.clear();
		
		for (String attribute : attributes) {
			xBox.addItem(attribute);
			yBox.addItem(attribute);
		}
	}
	
	/**
	 *  @see ByronClient.setSuggestions
	 */
	public void setSuggestions(List<String> suggestions) {
		oracle.clear();

		for (String s : suggestions) {
			oracle.add(s);
		}
	}
	
	public ChartPanel(GChart chart) {
		this(chart, null, null);
	}
	
	public void addXBoxListener(ChangeHandler ch) {
		xBox.addChangeHandler(ch);
	}
	
	public void addYBoxListener(ChangeHandler ch) {
		yBox.addChangeHandler(ch);
	}
	
	public void addSuggestionListener(KeyPressHandler handler) {
		suggBox.addKeyPressHandler(handler);
	}
	
	public void changeXValues(List<CellData> values) {
		final Curve curve = chart.getCurve();
		if (curve.getNPoints() == 0) {
			setAxisValues(values, values);
		}
		else {
			for (int i=0; i < curve.getNPoints(); ++i) {
				final Point point = curve.getPoint(i);
				point.setX(values.get(i).toDouble());
			}
		}
		chart.update();
	}
	
	public void changeYValues(List<CellData> values) {
		final Curve curve = chart.getCurve();
		
		if (curve.getNPoints() == 0) {
			setAxisValues(values, values);
		}
		else {
			for (int i=0; i < curve.getNPoints(); ++i) {
				final Point point = curve.getPoint(i);
				point.setY(values.get(i).toDouble());
			}	
		}
		chart.update();
	}
	
	public void setAxisValues(List<CellData> xValues, List<CellData> yValues) {
		final StringBuilder sb = new StringBuilder();
		final Curve curve = chart.getCurve();
		curve.clearPoints();
		for (int i = 0; i < xValues.size(); ++i) {
			curve.addPoint(xValues.get(i).toDouble(), yValues.get(i).toDouble());
			sb.append(xValues.get(i).toDouble() + ", " + yValues.get(i).toDouble());
			sb.append("\n");
		}
		chart.update();
	}
	
	/**
	 * @return The value in the suggestion box
	 */
	public String getKey() {
		return suggBox.getText();
	}
	
	public String getXAttribute() {
		return xBox.getItemText(xBox.getSelectedIndex());
	}
	
	public String getYAttribute() {
		return yBox.getItemText(yBox.getSelectedIndex());
	}
	
	public GChart getChart() {
		return chart;
	}
}
